﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reactive.Linq;
using System.Text;

namespace QbservableCore.Serialization
{
    static internal class Constant
    {
        #region ToJson

        /// <summary>
        /// Covert to the json.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="state">The expression to json.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        public static void ToJson(ConstantExpression node, ExpressionToJson state)
        {
            JContainer json = state.JsonCurrent;
            // stub is a special const that represent server observable
            // therefore can be chained into other method call
            var stub = node.Value as IQbservableStub;
            bool isStub = stub != null;
            if (isStub || state.JsonCurrent is JArray)
                json = TranslationHelper.AppendJsonToCurrentAsArray(state, !isStub);

            var qbs = node.Value as IQbservable;
            if (isStub)
            {
                string categoryValue = state.Convention.FromKeyToConvention(Consts.Json.Target);
                json.AddProperty(Consts.Json.Category, Consts.Json.Target, state);
                json.AddPropertyRaw(Consts.Json.Value, stub.Key, state);
            }
            else if (qbs != null)
            {
                state.JsonCurrent = new JArray();

                var r1 = node.Value.GetType().GetProperty("Source", Consts.Reflections.Default);
                var source = r1.GetValue(node.Value, null) as IQbservable;
                if (source != null)
                {
                    state.CreateAndTransform(source.Expression, state.JsonCurrent);
                }
                else
                    throw new NotImplementedException();
            }
            else
            {
                json.AddProperty(node.Type, state);
                json.AddPropertyRaw(Consts.Json.Value, node.Value.ToString(), state);
            }
        }

        #endregion // ToJson
    }
}
